/*
 * Copyright (c) 2021, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * （待验证）ADC单通道转换使用内部2.5V参考电压示例
 * 主函数循环启动ADC转换，OLED屏幕显示采样值
 * 旋转底板VR1滑动变阻器可以看到数值变化，控制蜂鸣器音量
 * 按键屏幕显示
 * Author: thy
 * 2025/05/18
 */
#include "key.h"
#include "oled.h"
#include "ti_msp_dl_config.h"

/* 检查adc是否完成转换 */
volatile bool gCheckADC;

volatile uint8_t data;

const unsigned char BMP_test[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x40, 0x60, 0x20, 0x20, 0x20,
    0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
    0x30, 0x30, 0x20, 0x20, 0x60, 0x40, 0x40, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60,
    0x10, 0x08, 0x0C, 0x06, 0x03, 0x01, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x03, 0x02, 0x04, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x78, 0x0C, 0x07, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFC, 0xFE, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE,
    0xFE, 0xFC, 0xF0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E,
    0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x60, 0xFC, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xE0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x8F, 0xEF, 0xE7,
    0xEF, 0xCF, 0xFF, 0xDF, 0xCF, 0xEF, 0xCF, 0x8F, 0x1F, 0x3F, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x87, 0x07, 0x03,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x0F, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F,
    0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xF0, 0xE0, 0xE1,
    0xE3, 0xE7, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7, 0xE7, 0xE7, 0xE3, 0xE0, 0xF0,
    0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x3F, 0x3F, 0x1F, 0x0F,
    0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x70, 0x1C, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60,
    0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1F,
    0x1F, 0x0F, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07,
    0x07, 0x03, 0x03, 0x07, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x80,
    0x80, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x06, 0x04, 0x0C, 0x08, 0x08, 0x18,
    0x10, 0x10, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    0x20, 0x20, 0x30, 0x10, 0x10, 0x10, 0x18, 0x08, 0x0C, 0x04, 0x06, 0x02,
    0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, /*"C:\Users\asus\Desktop\1683476646944.bmp",0*/

};
int key_value = 0;


// 串口发送字符串
void uart0_send_string(char *str) {
  // 当前字符串地址不在结尾 并且 字符串首地址不为空
  while (*str != 0 && str != 0) {
    // 发送字符串首地址中的字符，并且在发送完成之后首地址自增
    
    DL_UART_transmitDataBlocking(UART_0_INST,*str++);
  }
}

int main(void) {
  /* adc转换结果 */
  uint16_t adcResult, pecent; // adc转换结果（12bit，数字量）
  float adcResult_voltage; // adc转换结果对应的电压值（单位:mV）

  /* 系统初始化 */
  SYSCFG_DL_init();

  OLED_Init();
  OLED_Clear();
  OLED_ShowString(0, 0, "ADC val:");
  OLED_ShowString(0, 2, "voltage:");
  OLED_ShowString(104, 2, "mV");

  /* 开启 adc 中断 */
  NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
  /* 清除串口中断标志 */
  NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
  /* 使能串口中断 */
  NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
  /* 变量初始化 */
  gCheckADC = false;
  uart0_send_string("uart0 start work\r\n");
  /* 确保内部参考电压在adc转换前已完成配置 */
  while (DL_VREF_CTL1_READY_NOTRDY == DL_VREF_getStatus(VREF))
    ;
  DL_TimerA_startCounter(PWM_16KHz_INST); // 开定时器A1

  while (1) {
    /* 启动adc转换 */
    DL_ADC12_startConversion(ADC12_0_INST);

    /* 等待adc转换完成 */
    while (false == gCheckADC) {
      /* 进入低功耗模式 wait for event */
      __WFE();
    }

    /* 将adc采样值读出 */
    adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

    /* 根据公式计算对应的电压值，参考电压2.5V（sysconfig里设置） */
    adcResult_voltage =
        adcResult * 2500.0 / (4096.0 - 1) - 0.5 * 2500.0 / 4096.0;
    pecent = (uint32_t)adcResult * 1600.0 / 4095.0;

    /* 在OLED上显示采样值 */
    OLED_ShowNum(72, 0, adcResult, 4, 16);
    OLED_ShowNum(72, 2, (uint16_t)adcResult_voltage, 4, 16);

    /* 矩阵键盘更新 */
    key_value = getKeyValue();
    if (key_value != 0) {
      OLED_ShowNum(2, 6, (unsigned int)key_value, 2, 16);
    }

    /* 控制大概0.2s更新一次 */
    delay_cycles(32000000 * 0.1);

    /* 核心板LED翻转 */
    //      DL_GPIO_togglePins(LED_PORT,
    //      LED_PIN_2_PIN);

    /* 定时器A1占空比控制，蜂鸣器音量*/
    DL_TimerA_setCaptureCompareValue(PWM_16KHz_INST, pecent,
                                     DL_TIMER_CC_0_INDEX);

    /* 准备下一次采样 */
    gCheckADC = false;
    DL_ADC12_enableConversions(ADC12_0_INST);
  }
}

/* adc中断服务函数 */
void ADC12_0_INST_IRQHandler(void) {
  switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
  /* adc转换完成后进入中断 */
  case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
    gCheckADC = true;
    break;
  default:
    break;
  }
}

void UART_0_INST_IRQHandler(void) {
  switch (DL_UART_getPendingInterrupt(UART_0_INST)) // 检测是否串口中断
  {
  case DL_UART_IIDX_RX:
    data = DL_UART_Main_receiveData(UART_0_INST); // 发送接收到的数据
   // DL_UART_Main_transmitData(UART_0_INST, data);//直接写入
    DL_UART_transmitDataBlocking(UART_0_INST, data);//等待RX的FIFO为空写入
    /* 核心板LED翻转 */
    DL_GPIO_togglePins(LED_PORT, LED_PIN_2_PIN);
    break;
  default:
    break;
  }
}

